home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
comm
/
misc
/
xprzedzap090.lzh
/
Libinit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-30
|
5KB
|
159 lines
#define _USEOLDEXEC_ 1
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/memory.h>
#include <exec/resident.h>
#include <exec/libraries.h>
#include <libraries/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <string.h>
/* Version and Revision */
#define MYVERSION 0
#define MYREVISION 90
/* Prototypes */
ULONG __saveds __asm _LibExpunge( register __a6 struct MyLibrary *libbase );
ULONG __saveds __asm _LibInit( register __a0 APTR seglist,
register __d0 struct MyLibrary *libbase );
void __saveds __asm _UserLibInit(register __a6 struct MyLibrary *libbase );
void __saveds __asm _UserLibCleanup(register __a6 struct MyLibrary *libbase);
struct MyLibrary {
struct Library ml_Lib;
ULONG ml_SegList;
ULONG ml_Flags;
APTR ml_ExecBase; /* pointer to exec base */
};
typedef LONG (*PFL)(); /* pointer to function returning 32-bit int */
/* library initialization table, used for AUTOINIT libraries */
struct InitTable {
ULONG *it_DataSize; /* library data space size */
PFL *it_FuncTable; /* table of entry points */
APTR it_DataInit; /* table of data initializers */
PFL it_InitFunc; /* initialization function to run */
};
/* symbols generated by blink */
extern char __far _LibID[]; /* ID string */
extern char __far _LibName[]; /* Name string */
extern char __far RESLEN; /* size of init data */
extern long __far NEWDATAL; /* size of global data */
extern PFL _LibFuncTab[]; /* my function table */
#define DATAWORDS ((long)&NEWDATAL) /* magic to get right tpye of reloc */
#define SIZEJMPTAB ((long)libbase->ml_origbase->ml_numjmps)
/* size in bytes of jmp table */
/* From libent.o, needed to determine where data is loaded by loadseg */
extern long far _Libmergeddata;
struct InitTable __far _LibInitTab = {
(long *)(&RESLEN+sizeof(struct MyLibrary)),
_LibFuncTab,
NULL, /* will initialize my own data */
_LibInit,
};
__saveds __asm
ULONG _LibInit( register __a0 APTR seglist,
register __d0 struct MyLibrary *libbase )
{
long *reloc;
long *sdata;
char *ddata;
long nrelocs;
libbase->ml_SegList = (ULONG) seglist;
/* init. library structure (since I don't do automatic data init.) */
libbase->ml_Lib.lib_Node.ln_Type = NT_LIBRARY;
libbase->ml_Lib.lib_Node.ln_Name = _LibName;
libbase->ml_Lib.lib_Flags = LIBF_SUMUSED | LIBF_CHANGED;
libbase->ml_Lib.lib_Version = MYVERSION;
libbase->ml_Lib.lib_Revision = MYREVISION;
libbase->ml_Lib.lib_IdString = (APTR) _LibID;
/* Start of copy of global data after structure */
ddata = (char *)libbase + sizeof(struct MyLibrary);
sdata = (long *)&_Libmergeddata; /* where loadseg loaded the data */
memcpy(ddata, (void *)sdata, DATAWORDS*4);
/* perform relocs if we want one global section for all programs */
/* that have this lib open. If we want a global section for each */
/* open, copy the relocs, and do them on each open call. */
sdata = sdata + DATAWORDS;
nrelocs = *sdata;
sdata++;
while (nrelocs > 0)
{
reloc = (long *)((long)ddata + *sdata++);
*reloc += (long)ddata;
nrelocs--;
}
_UserLibInit(libbase);
return ( (ULONG) libbase );
}
LONG __saveds __asm
_LibOpen( register __a6 struct MyLibrary *libbase )
{
/* mark us as having another customer */
libbase->ml_Lib.lib_OpenCnt++;
/* clear delayed expunges (standard procedure) */
libbase->ml_Lib.lib_Flags &= ~LIBF_DELEXP;
return ( (LONG) libbase );
}
ULONG __saveds __asm
_LibClose( register __a6 struct MyLibrary *libbase )
{
ULONG retval = 0;
if (( --libbase->ml_Lib.lib_OpenCnt == 0 ) &&
( libbase->ml_Lib.lib_Flags & LIBF_DELEXP ))
{
/* no more people have me open,
* and I have a delayed expunge pending
*/
retval = _LibExpunge( libbase ); /* return segment list */
}
return (retval);
}
ULONG __saveds __asm
_LibExpunge( register __a6 struct MyLibrary *libbase )
{
ULONG seglist = 0;
LONG libsize;
libbase->ml_Lib.lib_Flags |= LIBF_DELEXP;
if ( libbase->ml_Lib.lib_OpenCnt == 0 )
{
/* really expunge: remove libbase and freemem */
_UserLibCleanup(libbase);
seglist = libbase->ml_SegList;
Remove( (struct Node *) libbase);
libsize = libbase->ml_Lib.lib_NegSize + libbase->ml_Lib.lib_PosSize;
FreeMem( (char *) libbase - libbase->ml_Lib.lib_NegSize,(LONG) libsize );
}
/* return NULL or real seglist */
return ( (ULONG) seglist );
}